package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm/logger"
	"gorm.io/gorm/schema"
	"log"
	"os"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var db *gorm.DB

//sqlx 是对 sql 进行的一层封装
func initializeDatabase() (err error) {
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer（日志输出的目标，前缀和日志包含的内容——译者注）
		logger.Config{
			SlowThreshold:             time.Second, // 慢 SQL 阈值
			LogLevel:                  logger.Info, // 日志级别
			IgnoreRecordNotFoundError: true,        // 忽略ErrRecordNotFound（记录未找到）错误
			Colorful:                  true,        // 禁用彩色打印
		},
	)
	//data source name
	//用户名@密码@协议(ip:port)/数据库
	dsn := "root:123456@tcp(gincloud:3306)/gin_demo?charset=utf8mb4&parseTime=True&loc=Local"
	db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		//日志配置
		Logger: newLogger,
		//自定义表名格式
		NamingStrategy: schema.NamingStrategy{
			//自定义表名前缀
			TablePrefix: "t_",
			//单数模式(表名后不加s)
			SingularTable: true,
		},
	})
	if err != nil {
		panic(err)
	}
	return nil
}

/*
关系练习:
一个学生有唯一的一张身份证
一个学生有一个班级, 一个班级有多个学生
一个学生有多个老师, 一个老师有多个学生
*/

type Class struct {
	gorm.Model
	ClassName string
	//一个班级有多个学生
	Students []Student
}

type Student struct {
	gorm.Model
	StudentName string
	ClassID     uint
	//学生和身份证关联
	IDCard IDCard
	//一个学生有多个老师
	Teachers []Teacher `gorm:"many2many:Student_Teacher;"`
}

type IDCard struct {
	gorm.Model
	Num  uint
	Addr string
	//身份证关联学生
	StudentID uint
}

type Teacher struct {
	gorm.Model
	TeacherName string
	//一个老师有多个学生
	Students []Student `gorm:"many2many:Student_Teacher;"`
}

func main() {
	//连接数据库
	if err := initializeDatabase(); err != nil {
		panic(err)
	}
	fmt.Println("connected")

	// 迁移 schema(根据 Student 结构自动创建表)
	db.AutoMigrate(&Class{}, &Student{}, &IDCard{}, &Teacher{})

	r := gin.Default()
	//创建班级
	// http://localhost:8080/class
	r.POST("class", func(c *gin.Context) {
		db.Create(&Class{ClassName: "go-web"})
		c.JSON(200, gin.H{
			"msg": "success",
		})
	})

	// http://localhost:8080/student
	r.POST("student", func(c *gin.Context) {
		var stu Student
		_ = c.ShouldBindJSON(&stu)
		db.Create(&stu)
		c.JSON(200, gin.H{
			"msg": "success",
		})
	})

	r.Run()

}
